---------------------------------------------------------------
File name   :  vv_ahblite_master_seq_lib.e
Title       :  Sequence library for the master agent
Project     :  vv_ahblite eVC
Developers  :  stefan,filip
Created     :  27.07.2011.
Description :  This file implements several sequence kinds
Notes       :  Each sequence implements a typical scenario or a
    :  combination of existing scenarios. Cadence recommends
    :  defining the sequence library in a separate file or
    :  files that can be loaded on top of the environment.
    :  This lets you include or exclude some sequence kinds
    :  according to the requirement of specific tests.
---------------------------------------------------------------
Copyright  (c)2011
---------------------------------------------------------------

<'
package vv_ahblite;

-- -------------------------------------------------------------------------
-- Use this section to modify the example sequence and add new sequences
-- to the master eVC sequence library.
-- Each sequence implements a different test scenario. For example, the
-- following sequence generates a write transaction followed by a read 
-- transaction, both with the same address. When using a RAM
-- slave model, the read transaction should return the same
-- data that was written.
-- To do so edit the following sequence definition and add new sequences: 

-- Step 1 - Add new type to the sequence kind
extend vv_ahblite_master_sequence_kind_t : [PROB_BUSY_AFTER_IDLE, PROBLEM_SEQ, SINGLE_WRITE, SINGLE_READ, WRAP4_RW,INCR4_RW, INCR8_RW, INCR16_RW, WRAP8_RW, WRAP16_RW, INCR_RW,INCR_BUSY_RW ];

extend PROB_BUSY_AFTER_IDLE vv_ahblite_master_sequence {
		
	body() @driver.clock is only{
		idle(0,BYTE);
		busy(0x0000003A, SINGLE, WORD, 1);	
	};	
};


extend PROB_BUSY_AFTER_IDLE vv_ahblite_master_sequence {
		
	body() @driver.clock is only{
		idle(0,BYTE);
		busy(0x0000003A, SINGLE, WORD, 1);	
	};	
};

extend PROBLEM_SEQ vv_ahblite_master_sequence {
		
	w_data      : list of vv_ahblite_data_t;
	keep soft w_data == {5};
	
	
	body() @driver.clock is only{
		
		var data: list of byte;
		
		unpack(packing.low,w_data,data);
		
		single_write(0x000000AA, data, SINGLE, NONSEQ, WORD);
		single_write(0x000000BB, data, SINGLE, SEQ, WORD);
	  };
};

-- Step 2 - Implement the new sequence 
extend SINGLE_WRITE vv_ahblite_master_sequence { --generates random number of consequent SINGLE WRITE transfers
	idle			:int; -- number of idle transfers during sequence
	keep soft idle == 0;
	
	keep gen (w_data) before (idle);
	
    start_address : vv_ahblite_addr_t;
    	
    w_data      : list of vv_ahblite_data_t;
    	keep soft w_data.size() in [1..10];
    size: vv_ahblite_data_size_t;
    mask : uint (bits : 32);
    
    max_addr : vv_ahblite_addr_t;
    keep max_addr < 65535;    

    body() @driver.clock is only{
        message(MEDIUM, "Starting SINGLE_WRITE Seq for address :",start_address);
        
        var data: list of byte;
         var idle_len :uint;
          
        for i from 0 to w_data.size()-1 do {
        	
        	size = BYTE;    	
        	if w_data[i] > 65535 then {size = WORD;}
        	else if w_data[i] > 255 then {size = HALFWORD;};
            
        	case size {
        		BYTE: { mask = 0xFFFFFFFF; };
        		HALFWORD:  { mask = 0xFFFFFFFE; };
        		WORD:  { mask = 0xFFFFFFFC; };
        	};
                    
            gen start_address keeping {it<max_addr;};
            start_address = start_address & mask;
            
            gen data keeping {  
            	(size == BYTE => .size() == 1) ;
            	(size == HALFWORD => .size() == 2) ;
            	(size == WORD => .size() == 4);
            };
            
            
            if(idle>0 ){
				gen idle_len keeping {it in [0..5]};
				for i from 1 to idle_len { 
					idle(start_address, size);
					idle-=1;
				};
			};	
            
            unpack(packing.low,w_data[i],data);
            single_write(start_address, data, SINGLE, NONSEQ, size);
        };
                      
        message(MEDIUM, "Ending SINGLE_WRITE Seq for address :",start_address);
    };
};

extend SINGLE_READ vv_ahblite_master_sequence { --generates random number of consequent SINGLE READ transfers
	
	idle			:int; -- number of idle transfers during sequence
		keep soft idle == 0;
	
    start_address : vv_ahblite_addr_t;

    !r_data   : vv_ahblite_data_t;
    
    size: vv_ahblite_data_size_t;
    mask : uint (bits : 32);
    num:uint (bits:4);
    keep gen (num ) before (idle);
    
    max_addr : vv_ahblite_addr_t;
    keep max_addr < 65535;    

    body() @driver.clock is only{
        message(MEDIUM, "Starting BASIC Read Seq for address :",start_address);
        
        
         var idle_len :uint; 
         
         for i from 1 to num do{    
        	gen size;
        	
        	case size {
			BYTE: { mask = 0xFFFFFFFF; };
			HALFWORD:  { mask = 0xFFFFFFFE; };
			WORD:  { mask = 0xFFFFFFFC; };
            	};
        	
        	gen start_address keeping {it<max_addr;};
        	start_address = start_address & mask;	
        	
             if(idle>0 ){
				gen idle_len keeping {it in [0..5]};
				for i from 1 to idle_len { 
					idle(start_address,size);
					idle-=1;
				};
			};	
             
            r_data = pack(packing.low, single_read(start_address, SINGLE,NONSEQ,size));
            
            
            --@@@@ nije validna procitana vrednost
            message(MEDIUM, "Read transaction addr: ",start_address ," = r_data :",r_data);
            
        };
        message(MEDIUM, "Ending BASIC Read Seq for address :",start_address);
    };
};

extend WRAP4_RW vv_ahblite_master_sequence {
	busy			:int; -- number of busy transfers during burst
		keep soft busy == 0;
	start_address 	: vv_ahblite_addr_t; 
		keep soft start_address == 0x00000000;
	w_data			: list of vv_ahblite_data_t;
		keep w_data.size() == 4;
	data_size		:	vv_ahblite_data_size_t;
		--keep soft data_size == WORD;
	write			:bit;
	 
	body()	@driver.clock is only {
		message(MEDIUM, "Starting WRAP4 burst Seq for address :",start_address);
		
		var data: list of byte;
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		case data_size {
        	BYTE: { mask = 0xFFFFFFFF; };
        	HALFWORD:  { mask = 0xFFFFFFFE; };
        	WORD:  { mask = 0xFFFFFFFC; };
        };
        start_address = start_address & mask;
				
		if write == 1 {
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, WRAP4, NONSEQ, data_size);
		}else {data = single_read(start_address, WRAP4, NONSEQ, data_size)};  
		
		
		var offset: uint (bits:32) = 1;       
        if data_size == HALFWORD { offset <<=1 ;}
        else if data_size == WORD { offset <<=2;};
        -- wrapping boundary
        var boundary:uint =4*offset;
        var wrap_start :uint = start_address/boundary;
        var busy_len :uint;
        	
        
		for i from 1 to 3 do {
			start_address+= offset;
			message(HIGH, "* * * adresa = ",start_address);
			message(HIGH, "* * * boundary = ",boundary);
			message(HIGH, "* * * wrap_start = ",wrap_start);
			
			if(start_address/boundary != wrap_start)
				{
					message(HIGH, "* * * WRAP PREKORACENJE, stara adresa:",start_address);
					start_address = wrap_start*boundary;
					message(HIGH, "* * * WRAP PREKORACENJE, nova adresa:",start_address);
				};
				
			-- if busy > 0 insert random number of busy transfers
			if(busy>0 and i<3){
				gen busy_len keeping {it in [0..5]};
				for i from 1 to busy_len { 
					busy(start_address, WRAP4, data_size, write);
					busy-=1;
				};
			};	
				
			if write == 1 {
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, WRAP4, SEQ, data_size);
			}else {data = single_read(start_address, WRAP4, SEQ, data_size)};  
			
		};
        message(MEDIUM, "Ending WRAP4 burst Seq for address :",start_address);
        
	};	
};

extend INCR4_RW vv_ahblite_master_sequence {
		busy			:int; -- number of busy transfers during burst
		keep soft busy == 0;
		start_address 	: vv_ahblite_addr_t; 
		keep soft start_address == 0x00000000;
		w_data			: list of vv_ahblite_data_t;
		keep w_data.size() == 4;
		data_size		:	vv_ahblite_data_size_t;
		--keep soft data_size == WORD;
		write			:bit;
	 
	body()	@driver.clock is only {
		message(MEDIUM, "Starting INCR4 burst Seq for address :",start_address);
		
		var data: list of byte;
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		
		case data_size {
			BYTE: { mask = 0xFFFFFFFF; };
			HALFWORD:  { mask = 0xFFFFFFFE; };
			WORD:  { mask = 0xFFFFFFFC; };
		};
		start_address = start_address & mask;
		
		----making sure that address does not cross 1 KB boundary
		
		if (start_address & 0x03F0) == 0x03F0 then
		{
			message(LOW,"reset address because of 1KB address cross for address: ",start_address);
			start_address = start_address & 0xFFF0; --reset four lowest bits
		};
		
		----------------------
		
		if write == 1 {
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, INCR4, NONSEQ, data_size);
		}else {data = single_read(start_address, INCR4, NONSEQ, data_size)};  
		
		
		var offset: uint (bits:32) = 1;       
        if data_size == HALFWORD { offset <<=1 ;}
        else if data_size == WORD { offset <<=2;};

        var busy_len :uint;
        	
        
		for i from 1 to 3 do {
			start_address+= offset;
			
			-- if busy > 0 insert random number of busy transfers
			if(busy>0 and i<3){
				gen busy_len keeping {it in [0..2]};
				for i from 1 to busy_len { 
					busy(start_address, INCR4, data_size, write);
					busy-=1;
				};
			};	
				
			if write == 1 {
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, INCR4, SEQ, data_size);
			}else {data = single_read(start_address, INCR4, SEQ, data_size)};  
			
		};
        message(MEDIUM, "Ending INCR4 burst Seq for address :",start_address);
        
	};	
	
};

extend INCR8_RW vv_ahblite_master_sequence {
		busy			:int; -- number of busy transfers during burst
		keep soft busy == 0;
		
		start_address 	: vv_ahblite_addr_t; 
		keep soft start_address == 0x00000000;
		
		w_data			: list of vv_ahblite_data_t;
		keep w_data.size() == 8;
		
		data_size		:	vv_ahblite_data_size_t;
		--keep soft data_size == WORD;
		write			:bit;
	 
	body()	@driver.clock is only {
		message(MEDIUM, "Starting INCR8 burst Seq for address :",start_address);
		
		var data: list of byte;
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		
		case data_size {
        	BYTE: { mask = 0xFFFFFFFF; };
        	HALFWORD:  { mask = 0xFFFFFFFE; };
        	WORD:  { mask = 0xFFFFFFFC; };
        };
        start_address = start_address & mask;
        
        ----making sure that address does not cross 1 KB boundary
		
		if (start_address & 0x03E0) == 0x03E0 then
		{
			message(LOW,"reset address because of 1KB address cross for address: ",start_address);
			start_address = start_address & 0xFFE0; --reset five lowest bits
		};
		
		----------------------
				
		if write == 1 {
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, INCR8, NONSEQ, data_size);
		}else {data = single_read(start_address, INCR8, NONSEQ, data_size)};  
		
		
		var offset: uint (bits:32) = 1;       
        if data_size == HALFWORD { offset <<=1 ;}
        else if data_size == WORD { offset <<=2;};

        var busy_len :uint;
        	
        
		for i from 1 to 7 do {
			start_address+= offset;
			
			-- if busy > 0 insert random number of busy transfers
			if(busy>0 and i<7){
				gen busy_len keeping {it in [0..2]};
				for i from 1 to busy_len { 
					busy(start_address, INCR8, data_size, write);
					busy-=1;
				};
			};	
				
			if write == 1 {
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, INCR8, SEQ, data_size);
			}else {data = single_read(start_address, INCR8, SEQ, data_size)};  
			
		};
        message(MEDIUM, "Ending INCR8 burst Seq for address :",start_address);
        
	};	
	
};

extend INCR16_RW vv_ahblite_master_sequence {
		busy			:int; -- number of busy transfers during burst
		keep soft busy == 0;
		
		start_address 	: vv_ahblite_addr_t; 
		keep soft start_address == 0x00000000;
		
		w_data			: list of vv_ahblite_data_t;
		keep w_data.size() == 16;
		
		data_size		:	vv_ahblite_data_size_t;
		--keep soft data_size == WORD;
		write			:bit;
	 
	body()	@driver.clock is only {
		message(MEDIUM, "Starting INCR16 burst Seq for address :",start_address);
		
		var data: list of byte;
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		
		case data_size {
        	BYTE: { mask = 0xFFFFFFFF; };
        	HALFWORD:  { mask = 0xFFFFFFFE; };
        	WORD:  { mask = 0xFFFFFFFC; };
        };
        start_address = start_address & mask;
        
        ----making sure that address does not cross 1 KB boundary
		
		if (start_address & 0x03C0) == 0x03C0 then
		{
			message(LOW,"reset address because of 1KB address cross for address: ",start_address);
			start_address = start_address & 0xFFC0; --reset six lowest bits
		};
		
		----------------------
		
		if write == 1 {
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, INCR16, NONSEQ, data_size);
		}else {data = single_read(start_address, INCR16, NONSEQ, data_size)};  
		
		
		var offset: uint (bits:32) = 1;       
        if data_size == HALFWORD { offset <<=1 ;}
        else if data_size == WORD { offset <<=2;};

        var busy_len :uint;
        	
        
		for i from 1 to 15 do {
			start_address+= offset;
			
			-- if busy > 0 insert random number of busy transfers
			if(busy>0 and i<15){
				gen busy_len keeping {it in [0..2]};
				for i from 1 to busy_len { 
					busy(start_address, INCR16, data_size, write);
					busy-=1;
				};
			};	
				
			if write == 1 {
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, INCR16, SEQ, data_size);
			}else {data = single_read(start_address, INCR16, SEQ, data_size)};  
			
		};
        message(MEDIUM, "Ending INCR16 burst Seq for address :",start_address);
        
	};	
	
};

extend WRAP8_RW vv_ahblite_master_sequence {
	busy			:int; -- number of busy transvers during burst
		keep soft busy == 0;
	start_address 	: vv_ahblite_addr_t; 
		keep soft start_address == 0x00000000;
	w_data			: list of vv_ahblite_data_t;
		keep w_data.size() == 8;
	data_size		:	vv_ahblite_data_size_t;
		--keep soft data_size == WORD;
	write			:bit;
	 
	body()	@driver.clock is only {
		message(MEDIUM, "Starting WRAP8 burst Seq for address :",start_address);
		
		var data: list of byte;
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		
		case data_size {
        		BYTE: { mask = 0xFFFFFFFF; };
        		HALFWORD:  { mask = 0xFFFFFFFE; };
        		WORD:  { mask = 0xFFFFFFFC; };
        	};
        start_address = start_address & mask;
		
		
		if write == 1 {
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, WRAP8, NONSEQ, data_size);
		}else {data = single_read(start_address, WRAP8, NONSEQ, data_size)};  
		
		
		var offset: uint (bits:32) = 1;       
        if data_size == HALFWORD { offset <<=1 ;}
        else if data_size == WORD { offset <<=2;};
        -- wrapping boundary
        var boundary:uint = 8*offset;
        var wrap_start :uint = start_address/boundary;
        var busy_len :uint;
        	
        
		for i from 1 to 7 do {
			start_address+= offset;
			if(start_address/boundary != wrap_start)
				{start_address = wrap_start*boundary};
				
			-- if busy > 0 insert random number of busy transfers
			if(busy>0 and i<7){
				gen busy_len keeping {it in [0..2]};
				for i from 1 to busy_len { 
					busy(start_address, WRAP8, data_size, write);
					busy-=1;
				};
			};	
				
			if write == 1 {
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, WRAP8, SEQ, data_size);
			}else {data = single_read(start_address, WRAP8, SEQ, data_size)};  
			
		};
        message(MEDIUM, "Ending WRAP8 burst Seq for address :",start_address);
        
	};	
};

extend WRAP16_RW vv_ahblite_master_sequence {
	busy			:int; -- number of busy transvers during burst
		keep soft busy == 0;
	start_address 	: vv_ahblite_addr_t; 
		keep soft start_address == 0x00000000;
	w_data			: list of vv_ahblite_data_t;
		keep w_data.size() == 16;
	data_size		:	vv_ahblite_data_size_t;
	--keep soft data_size == WORD;
	write			:bit;
	
	body()	@driver.clock is only {
		message(MEDIUM, "Starting WRAP16 burst Seq for address :",start_address);
		
		var data: list of byte;
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		
		case data_size {
        		BYTE: { mask = 0xFFFFFFFF; };
        		HALFWORD:  { mask = 0xFFFFFFFE; };
        		WORD:  { mask = 0xFFFFFFFC; };
        	};
        start_address = start_address & mask;
        
		if write == 1 {
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, WRAP16, NONSEQ, data_size);
		}else {data = single_read(start_address, WRAP16, NONSEQ, data_size)};  
		
		
		var offset: uint (bits:32) = 1;       
		if data_size == HALFWORD { offset <<=1 ;}
		else if data_size == WORD { offset <<=2;};
		-- wrapping boundary
		var boundary:uint = 16*offset;
		var wrap_start :uint = start_address/boundary;
		var busy_len :uint;
		
		
		for i from 1 to 15 do {
			start_address+= offset;
			if(start_address/boundary != wrap_start)
			{start_address = wrap_start*boundary};
			
			-- if busy > 0 insert random number of busy transfers
			if(busy>0 and i<15){
				gen busy_len keeping {it in [0..2]};
				for i from 1 to busy_len { 
					busy(start_address, WRAP16, data_size, write);
					busy-=1;
				};
			};	
			
			if write == 1 {
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, WRAP16, SEQ, data_size);
			}else {data = single_read(start_address, WRAP16, SEQ, data_size)};  
			
		};
		message(MEDIUM, "Ending WRAP16 burst Seq for address :",start_address);
		
	};	
};

--incrementing burst of undefined length
extend INCR_RW vv_ahblite_master_sequence {
	busy			:int; -- number of busy transvers during burst
		keep soft busy == 0;
	start_address 	: vv_ahblite_addr_t; 
		--keep soft start_address == 0x00000000;
	w_data			: list of vv_ahblite_data_t;
		keep soft w_data.size() in [1..10];
	data_size		:	vv_ahblite_data_size_t;
	--keep soft data_size == WORD;
	write			:bit;
	
	body()	@driver.clock is only {
		message(MEDIUM, "Starting INCR burst Seq for address :",start_address);
		
		var data: list of byte;
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		
		case data_size {
        	BYTE: { mask = 0xFFFFFFFF; };
        	HALFWORD:  { mask = 0xFFFFFFFE; };
        	WORD:  { mask = 0xFFFFFFFC; };
        };
        start_address = start_address & mask;
				
		if write == 1 {
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, INCR, NONSEQ, data_size);
		}else {data = single_read(start_address, INCR, NONSEQ, data_size)};  	
		
		var offset: uint (bits:32) = 1;       
		if data_size == HALFWORD { offset <<=1 ;}
		else if data_size == WORD { offset <<=2;};	
		
		var busy_len :uint;

		for i from 1 to w_data.size()-1 do {
			start_address+= offset;
			-- if busy > 0 insert random number of busy transfers
			if(busy>0){
				gen busy_len keeping {it in [0..2]};
				for i from 1 to busy_len { 
					busy(start_address, INCR, data_size, write);
					busy-=1;
				};
			};	
			
			if write == 1 {
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, INCR, SEQ, data_size);
			}else {data = single_read(start_address, INCR, SEQ, data_size)};  
			
		};
		message(MEDIUM, "Ending INCR burst Seq for address :",start_address);
		
	};
	
};
	
	extend INCR_BUSY_RW vv_ahblite_master_sequence {
		
	busy			:int; -- number of busy transvers during burst
		keep soft busy == 0;
	start_address 	: vv_ahblite_addr_t; 
		--keep soft start_address == 0x00000000;
	w_data			: list of vv_ahblite_data_t;
		keep soft w_data.size() in [1..10];
	data_size		:	vv_ahblite_data_size_t;
	--keep soft data_size == WORD;
	write			:bit;
	
	
	body()	@driver.clock is only {
		message(MEDIUM, "Starting INCR BUSY ended burst for address :",start_address);
		
		var data: list of byte;
		
		gen data keeping {
			data_size == BYTE => .size() == 1;
			data_size == HALFWORD => .size() == 2;
			data_size == WORD => .size() == 4;
		};
		var mask : uint (bits : 32);
		
		case data_size {
        	BYTE: { mask = 0xFFFFFFFF; };
        	HALFWORD:  { mask = 0xFFFFFFFE; };
        	WORD:  { mask = 0xFFFFFFFC; };
        };
        start_address = start_address & mask;
				
		if write == 1 
		{
			unpack(packing.low,w_data[0],data);
			single_write(start_address, data, INCR, NONSEQ, data_size);
		}
		else 
		{
			data = single_read(start_address, INCR, NONSEQ, data_size)
		};  	
		
		var offset: uint (bits:32) = 1;       
		
		if data_size == HALFWORD { offset <<=1; }
		else if data_size == WORD { offset <<=2; };	
		
		var busy_len :uint;
		
		var do_break: uint;
		gen do_break keeping {it in [1..10];};

		for i from 1 to w_data.size()-1 do {
			start_address+= offset;
			-- if busy > 0 insert random number of busy transfers
			if(busy>0){
				gen busy_len keeping {it in [0..2]};
				for i from 1 to busy_len { 
					busy(start_address, INCR, data_size, write);
					busy-=1;
				};
			};	
			
			if (i == do_break) then 
				{ 
					busy(start_address, INCR, data_size, write); 
					break;
				};
			
			
			if write == 1 
			{
				unpack(packing.low,w_data[i],data);
				single_write(start_address, data, INCR, SEQ, data_size);
			}
			else 
			{
				data = single_read(start_address, INCR, SEQ, data_size)
			};  
			
		};
		
		if ( do_break%3 == 0 )   
			{ idle(start_address, data_size); };
			
		message(MEDIUM, "Ending INCR BUSY ended burst for address : :",start_address);
		
	};	
};

-- Step 3 - Iterate Step 1 and Step 2 to create more sequences as required.

-- Note - Cadence recommends encapsulating any meaningful scenario as a
--        new sequence kind.
-- *************************************************************************
 
'>

